using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;

namespace WL.Think.Abp.Entities;

/// <summary>
/// 分类基类
/// </summary>
/// <typeparam name="TCategory"></typeparam>
[Serializable]
[Index(nameof(Path))]
public abstract class BaseCategory<TCategory,TKey> : BaseEntity<TKey> where TCategory : BaseCategory<TCategory, TKey> 
    where TKey : struct, IComparable<TKey>
{
    protected BaseCategory() { }

    protected BaseCategory(TKey id, Guid? tenantId = null) : base(id, tenantId)
    {
        Children = new List<TCategory>();
    }

    protected BaseCategory(TKey id, string name, bool isActive, string description, int index, Guid? tenantId = null):this(id, tenantId)
    {
        Name = name;
        IsActive = isActive;
        Description = description;
        Index = index;
        Path = id.ToString()!;
    }


    /// <summary>
    /// 名称
    /// </summary>
    [Required]
    [Comment("名称")]
    [MaxLength(128)]
    public required string Name { get; set; }

    /// <summary>
    /// 路径
    /// </summary>
    [Required]
    [Comment("路径")]
    [MaxLength(2048)]
    public required string Path { get; set; }

    /// <summary>
    /// 上级ID
    /// </summary>
    [Comment("上级ID")]
    public TKey? ParentId { get; set; }

    /// <summary>
    /// 是否启用
    /// </summary>
    [Comment("是否启用")]
    public bool IsActive { get; set; }

    /// <summary>
    /// 描述
    /// </summary>
    [Comment("描述")]
    [MaxLength(2048)]
    public string? Description { get; set; }

    /// <summary>
    /// 排序
    /// </summary>
    [Comment("排序")]
    public int Index { get; set; }

    /// <summary>
    /// 层级
    /// </summary>
    [NotMapped]
    public int Level => Path.IsNullOrWhiteSpace() ? 0 : Path.Split(".").Length;

    /// <summary>
    /// 根节点
    /// </summary>
    [NotMapped]
    public bool IsRoot => Level == 1;
    
    /// <summary>
    /// 叶子节点
    /// </summary>
    [NotMapped]
    public bool IsLeaf => Children.Count == 0;

    /// <summary>
    /// 子分类列表
    /// </summary>
    [ForeignKey(nameof(ParentId))]
    public virtual ICollection<TCategory> Children { get; set; } = [];


    /// <summary>
    /// 设置上级分类
    /// </summary>
    /// <param name="parent"></param>
    public void SetParent(TCategory? parent, int? index = null)
    {
        if (parent != null)
        {
            ParentId = parent.Id;
            Path = $"{parent.Path}.{Id}";
            Index = index ?? Index;
            LastModificationTime = DateTime.Now;

            if (parent.Children != null && !parent.Children.Contains(this))
            {
                parent.Children.Add((TCategory)this);
            }

            if (Children != null && Children.Count != 0)
            {
                foreach (var item in Children)
                {
                    item.SetParent((TCategory)this, item.Index);
                }
            }
        }
        else
        {
            Path = Id.ToString()!;
            return;
        }
    }

    /// <summary>
    /// 添加子类
    /// </summary>
    /// <param name="child"></param>
    public void AddChild(params TCategory?[] children)
    {
        foreach (var item in children)
        {
            if(item != null)
            {
                item.SetParent((TCategory)this);
            }
        }
    }


    /// <summary>
    /// 替换匹配路径
    /// </summary>
    /// <param name="matchPath"></param>
    /// <param name="newPath"></param>
    public void ReplacePath(string matchPath, string newPath)
    {
        if (Path.StartsWith(matchPath))
        {
            Path = Path.Replace(matchPath, newPath);
        }

        if(Children !=null && Children.Count != 0)
        {
            foreach (var item in Children)
            {
                item.ReplacePath(matchPath, newPath);
            }
        }
    }                                                              
}

public abstract class BaseCategory<TCategory> : BaseCategory<TCategory,Guid> where TCategory : BaseCategory<TCategory>
{

}